package com.zbkj.crmeb.order.channel;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

import javax.annotation.Resource;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.zbkj.crmeb.chant.model.ChannelMerchantAccount;
import com.zbkj.crmeb.enums.*;
import com.zbkj.crmeb.plat.by.dto.Result;
import com.zbkj.crmeb.store.model.PurchaseGoods;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.crmeb.core.common.CommonResult;
import com.constants.Constants;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.utils.PriceUtil;
import com.crmeb.core.config.RestTemplateConfig;
import com.zbkj.crmeb.order.AbstractStoreOrderService;
import com.zbkj.crmeb.order.StoreOrderFactory;
import com.zbkj.crmeb.order.response.ImOrderInfoResponse;
import com.zbkj.crmeb.order.response.ImOrderLogisticsInfoResponse;
import com.zbkj.crmeb.order.response.ImOrderResponse;
import com.zbkj.crmeb.store.dao.StoreOrderDao;
import com.zbkj.crmeb.store.model.StoreOrder;
import com.zbkj.crmeb.store.model.StoreProductAttrValue;
import com.zbkj.crmeb.store.service.StoreProductAttrValueService;
import com.zbkj.crmeb.store.service.StoreProductService;
import com.zbkj.crmeb.store.vo.StoreOrderInfoVo;
import com.zbkj.crmeb.system.model.SystemConfig;
import com.zbkj.crmeb.system.service.SystemConfigService;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class ImStoreOrderServiceImpl extends AbstractStoreOrderService {

    @Resource
    private StoreOrderDao storeOrderDao;
    @Autowired
    RestTemplateConfig restTemplateConfig;
    @Autowired
    SystemConfigService systemConfigService;
    @Autowired
    StoreProductService storeProductService;
    @Autowired
    StoreProductAttrValueService storeProductAttrValueService;
    @Resource
    private PriceUtil priceUtil;
    @Autowired
    StoreOrderFactory storeOrderFactory;

    /********* IM配置参数  *********/
    @Value("${im.url.createOrder}")
    private String imCreateOrderUrl;
    @Value("${im.appKey}")
    private String imAppKey;
    @Value("${im.appSecret}")
    private String imAppSecret;
    @Value("${im.url.domain}")
    private String imDomainUrl;
    @Value("${im.url.token}")
    private String imTokenUrl;
    @Value("${im.url.orderInfo}")
    private String imOrderInfoUrl;
    @Value("${im.url.orderLogisticsInfo}")
    private String imOrderLogisticsInfoUrl;
    @Value("${im.url.orderCancel}")
    private String imOrderCancel;

    @Override
	public CommonResult<Object> addChannelOrder(StoreOrder storeOrder, List<StoreOrderInfoVo> orderInfoVoList) {
        List<String> errorMessages = new ArrayList<>();
        try {
			int num = 1;
			for (StoreOrderInfoVo order : orderInfoVoList) {
				for (int i = 0; i < order.getInfo().getCartNum(); i++) {
					// 组建订单对象
					StoreProductAttrValue info = order.getInfo().getProductInfo().getAttrInfo();
					String sourceSkuId = info.getSourceSkuId();
                    if(sourceSkuId.startsWith(ProductTypeEnum.IM.getCode()+"-")){
                        sourceSkuId = sourceSkuId.replaceFirst(ProductTypeEnum.IM.getCode()+"-","");
                    }
					long itemId = Long.parseLong(sourceSkuId);
					BigDecimal salePrice = priceUtil.rmb2EurStatic(info.getSourceCost(),order.getExchangeRate());
					JSONObject param = new JSONObject();
					param.put("itemId", itemId);
					param.put("salePrice", salePrice);
					if (9 != storeOrder.getSource()) {
                        storeOrder.setPushOrderNo(order.getChildOrderNumber()+ "-" + i);
					}
					param.put("channelOrderNo", storeOrder.getPushOrderNo());
                    param.put("platformAddressId",order.getActualSupplierAddressId());
                    Result result = pushOrder(storeOrder, param, order);
                    if(!result.isSuccess()){
                        errorMessages.add("订单号: " + order.getOrderInfoId() + ",错误: " + result.getMessage());
                    }
                    num++;
				}
			}
		} catch (Exception e) {
			log.info("--------------- 请求IM创建订单失败: {} ---------------", e.getMessage());
		}

        if (!errorMessages.isEmpty()) {
            return CommonResult.failed(String.join("\n", errorMessages));
        }
		return CommonResult.success();
	}

	private Result pushOrder(StoreOrder storeOrder, JSONObject param, StoreOrderInfoVo orderInfo) {
		String orderId = storeOrder.getSource() == 9 ? storeOrder.getOrderId().split("-")[0] : storeOrder.getOrderId();

		SystemConfig systemConfig = systemConfigService.getOne(
				Wrappers.<SystemConfig>lambdaQuery().eq(SystemConfig::getName, Constants.IM_TOKEN).last("LIMIT 1"));
		// 组装请求url
		StringBuilder sb = new StringBuilder();
		sb.append(imDomainUrl).append(imCreateOrderUrl);
		log.info("--------------- 开始请求IM创建订单url: {} ,参数:{}---------------", sb.toString(), param.toJSONString());
		RestTemplate restTemplate = restTemplateConfig.restTemplate();
		HttpHeaders headers = new HttpHeaders();
		headers.setContentType(MediaType.APPLICATION_JSON);
		headers.add("x-forwarded-for", "121.4.132.191");
		headers.add("access-token", systemConfig.getValue());
		HttpEntity<JSONObject> formEntity = new HttpEntity<>(param, headers);
		ResponseEntity<String> result = restTemplate.postForEntity(sb.toString(), formEntity, String.class);
		log.info("--------------- 请求IM创建订单返回结果: {} ---------------", result.toString());
		// 处理返回结果
		ObjectMapper mapper = new ObjectMapper();
		ImOrderResponse imOrderResponse = new ImOrderResponse();
		try {
			imOrderResponse = mapper.readValue(Objects.requireNonNull(result.getBody()), ImOrderResponse.class);
		} catch (JsonProcessingException e) {
			e.printStackTrace();
		}
		// 判定token失效
		if (!imOrderResponse.isSuccess() && imOrderResponse.getError().contains("access-token")) {
			log.info("--------------- 请求IM创建订单token失效,重新请求 ---------------");
			// 获取新的token
			SystemConfig imToken = getImToken(systemConfig);
			// 重新下订单
			headers.remove("access-token");
			headers.add("access-token", imToken.getValue());
			HttpEntity<JSONObject> httpEntity = new HttpEntity<>(param, headers);
			ResponseEntity<String> response = restTemplate.postForEntity(sb.toString(), httpEntity, String.class);
			log.info("--------------- 请求IM创建订单返回结果: {} ---------------", result.toString());
			try {
				imOrderResponse = mapper.readValue(Objects.requireNonNull(response.getBody()), ImOrderResponse.class);
			} catch (JsonProcessingException e) {
				e.printStackTrace();
			}
		}
		if (imOrderResponse.isSuccess()) {
			String orderLineNum = imOrderResponse.getData().getOrderLineNum();
			// 新增采购单
			storeOrderFactory.insertPurchaseOrder(storeOrder, true, PurchaseOrderChannelTypeEnum.IM.getCode());
			// 新增采购商品
			storeOrderFactory.insertPurchaseGoods(orderInfo, storeOrder, true, "IM推送: 成功", orderLineNum);
			StoreOrder storeOrderUpdate = new StoreOrder();
			storeOrderUpdate.setId(storeOrder.getId());
			storeOrderUpdate.setPushStatus(1);
			storeOrderUpdate.setPushMessage("IM推送: 成功");
			storeOrderDao.updateById(storeOrderUpdate);
			return new Result(true, null, "IM推送: 成功");
		}

		// 新增采购单
		storeOrderFactory.insertPurchaseOrder(storeOrder, false, PurchaseOrderChannelTypeEnum.IM.getCode());
		// 新增采购商品
		storeOrderFactory.insertPurchaseGoods(orderInfo, storeOrder, false, imOrderResponse.getError(), null);
		StoreOrder storeOrderUpdate = new StoreOrder();
		storeOrderUpdate.setId(storeOrder.getId());
		storeOrderUpdate.setPushStatus(2);
		storeOrderUpdate.setPushMessage("IM推送:失败 " + imOrderResponse.getError());

		storeOrderDao.updateById(storeOrderUpdate);

        return new Result(false, null, imOrderResponse.getError());
	}

    // 获取Im token
    public SystemConfig getImToken(SystemConfig systemConfigParam) {
        SystemConfig systemConfig = systemConfigService.getOne(Wrappers.<SystemConfig>lambdaQuery().eq(SystemConfig::getName, Constants.IM_TOKEN).last("LIMIT 1"));
        // token已被更新
        if (!systemConfig.getFormId().equals(systemConfigParam.getFormId())) {
            return systemConfig;
        }
        RestTemplate restTemplate = restTemplateConfig.restTemplate();
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        // TODO 待删除
        headers.add("x-forwarded-for", "121.4.132.191");
        JSONObject param = new JSONObject();
        param.put("appKey", imAppKey);
        param.put("appSecret", imAppSecret);
        HttpEntity<JSONObject> formEntity = new HttpEntity<>(param, headers);
        ResponseEntity<String> response = restTemplate.postForEntity(imDomainUrl + imTokenUrl, formEntity, String.class);
        log.info("--------------- IM授权获取token返回: {} ---------------", response);
        if (HttpStatus.OK == response.getStatusCode()) {
            String token = JSONObject.parseObject(response.getBody()).getJSONObject("data").getString("access_token");
            systemConfigParam.setValue(token);
            systemConfigParam.setFormId(systemConfigParam.getFormId() + 1);
            systemConfigParam.setUpdateTime(new Date());
            systemConfigService.updateById(systemConfigParam);
        }
        return systemConfigParam;
    }

    @Override
    public CommonResult<Object> cancelChannelOrder(StoreOrder storeOrder, List<StoreOrderInfoVo> orderInfoVoList) {
        return  null;
    }
    public CommonResult<Object> cancelChannelOrderByApi(PurchaseGoods purchaseGoods) {

        //2023.4.6 取消功能添加
        SystemConfig systemConfig = systemConfigService.getOne(Wrappers.<SystemConfig>lambdaQuery()
                .eq(SystemConfig :: getName, Constants.IM_TOKEN)
                .last("LIMIT 1"));
        // 组装请求url
        StringBuilder sb = new StringBuilder();
        sb.append(imDomainUrl).append(imOrderCancel);
        JSONObject param = new JSONObject();
        param.put("orderLineNum",purchaseGoods.getChannelOrderSn());
        log.info("--------------- 开始请求IM取消订单url: {} ,参数:{}---------------", sb.toString(),param.toJSONString());
        RestTemplate restTemplate = restTemplateConfig.restTemplate();
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.add("x-forwarded-for", "121.4.132.191");
        headers.add("access-token", systemConfig.getValue());
        HttpEntity<JSONObject> formEntity = new HttpEntity<>(param, headers);
        ResponseEntity<String> result = restTemplate.postForEntity(sb.toString(), formEntity, String.class);
        log.info("--------------- 请求IM取消订单返回结果: {} ---------------", result.toString());
        //处理返回结果

        ObjectMapper mapper = new ObjectMapper();
        ImOrderResponse imOrderResponse = new ImOrderResponse();
        try {
            imOrderResponse = mapper.readValue(Objects.requireNonNull(result.getBody()), ImOrderResponse.class);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        // 判定token失效
        if (!imOrderResponse.isSuccess() && imOrderResponse.getError().contains("access-token")) {
            log.info("--------------- 请求IM创建订单token失效,重新请求 ---------------");
            // 获取新的token
            SystemConfig imToken = getImToken(systemConfig);
            // 重新执行
            headers.remove("access-token");
            headers.add("access-token", imToken.getValue());
            HttpEntity<JSONObject> httpEntity = new HttpEntity<>(param, headers);
            ResponseEntity<String> response = restTemplate.postForEntity(sb.toString(), httpEntity, String.class);
            log.info("--------------- 请求IM取消订单返回结果: {} ---------------", result.toString());
            try {
                imOrderResponse = mapper.readValue(Objects.requireNonNull(response.getBody()), ImOrderResponse.class);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
        }
        if (imOrderResponse.isSuccess()) {

            return CommonResult.success();

        }else
        {
            return CommonResult.failed();

        }
    }

    /**
     * 查询订单信息
     * @param channelOrderSn im订单号
     * @return
     */
    public CommonResult<Object> getOrderInfo(String channelOrderSn){
        String[] sn = new String[] {channelOrderSn};
        SystemConfig systemConfig = systemConfigService.getOne(Wrappers.<SystemConfig>lambdaQuery()
                .eq(SystemConfig :: getName, Constants.IM_TOKEN)
                .last("LIMIT 1"));
        // 组装请求url
        StringBuilder sb = new StringBuilder();
        sb.append(imDomainUrl).append(imOrderInfoUrl);
        JSONObject param = new JSONObject();
        param.put("orderLineNums",sn);
        log.info("--------------- 开始请求IM查询订单url: {} ,参数:{}---------------", sb.toString(),param.toJSONString());
        RestTemplate restTemplate = restTemplateConfig.restTemplate();
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.add("x-forwarded-for", "121.4.132.191");
        headers.add("access-token", systemConfig.getValue());
        HttpEntity<JSONObject> formEntity = new HttpEntity<>(param, headers);
        ResponseEntity<String> result = restTemplate.postForEntity(sb.toString(), formEntity, String.class);
        log.info("--------------- 请求IM查询订单返回结果: {} ---------------", result.toString());
        //处理返回结果
        ObjectMapper mapper = new ObjectMapper();
        ImOrderInfoResponse imOrderInfoResponse = new ImOrderInfoResponse();
        try {
            imOrderInfoResponse = mapper.readValue(Objects.requireNonNull(result.getBody()), ImOrderInfoResponse.class);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        // 判定token失效
        if(!imOrderInfoResponse.isSuccess() && imOrderInfoResponse.getError().contains("access-token")){
            log.info("--------------- 请求IM查询订单token失效,重新请求 ---------------");
            //获取新的token
            SystemConfig imToken = getImToken(systemConfig);
            //重新下订单
            headers.remove("access-token");
            headers.add("access-token", imToken.getValue());
            HttpEntity<JSONObject> httpEntity = new HttpEntity<>(param, headers);
            ResponseEntity<String> response = restTemplate.postForEntity(sb.toString(), httpEntity, String.class);
            log.info("--------------- 请求IM查询订单返回结果: {} ---------------", result.toString());
            try {
                imOrderInfoResponse = mapper.readValue(Objects.requireNonNull(response.getBody()), ImOrderInfoResponse.class);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
        }
        if(CollectionUtils.isEmpty(imOrderInfoResponse.getData()) || imOrderInfoResponse.getData().get(0).getStatus() == null ){
            return CommonResult.failed();
        }
        return imOrderInfoResponse.isSuccess()? CommonResult.success(conversionType(imOrderInfoResponse.getData().get(0).getStatus()),"查询成功"): CommonResult.failed();
    }

    /**
     * 查询物流信息
     * @param channelOrderSn
     * @return
     */
    public CommonResult<Object> getOrderLogisticsInfo(String channelOrderSn){
        SystemConfig systemConfig = systemConfigService.getOne(Wrappers.<SystemConfig>lambdaQuery()
                .eq(SystemConfig :: getName, Constants.IM_TOKEN)
                .last("LIMIT 1"));
        // 组装请求url
        StringBuilder sb = new StringBuilder();
        sb.append(imDomainUrl).append(imOrderLogisticsInfoUrl).append("?orderLineNum=").append(channelOrderSn);
        log.info("--------------- 开始请求IM查询订单物流信息url: {} ---------------", sb.toString());
        RestTemplate restTemplate = restTemplateConfig.restTemplate();
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.add("x-forwarded-for", "121.4.132.191");
        headers.add("access-token", systemConfig.getValue());
        HttpEntity<String> formEntity = new HttpEntity<>(null,headers);
        ResponseEntity<String> result = restTemplate.exchange(sb.toString(), HttpMethod.GET, formEntity ,String.class);
        log.info("--------------- 请求IM查询订单物流信息返回结果: {} ---------------", result.toString());
        //处理返回结果
        ObjectMapper mapper = new ObjectMapper();
        ImOrderLogisticsInfoResponse imOrderInfoResponse = new ImOrderLogisticsInfoResponse();
        try {
            imOrderInfoResponse = mapper.readValue(Objects.requireNonNull(result.getBody()), ImOrderLogisticsInfoResponse.class);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        // 判定token失效
        if(!imOrderInfoResponse.isSuccess() && imOrderInfoResponse.getError().contains("access-token")){
            log.info("--------------- 请求IM查询订单物流信息token失效,重新请求 ---------------");
            //获取新的token
            SystemConfig imToken = getImToken(systemConfig);
            headers.remove("access-token");
            headers.add("access-token", imToken.getValue());
            HttpEntity<String> httpEntity = new HttpEntity<>(null,headers);
            ResponseEntity<String> response = restTemplate.exchange(sb.toString(), HttpMethod.GET, httpEntity ,String.class);
            log.info("--------------- 请求IM查询订单物流信息返回结果: {} ---------------", result.toString());
            try {
                imOrderInfoResponse = mapper.readValue(Objects.requireNonNull(response.getBody()), ImOrderLogisticsInfoResponse.class);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
        }
        return imOrderInfoResponse.isSuccess()? CommonResult.success(imOrderInfoResponse.getData(),"查询成功"): CommonResult.failed();
    }

    private String conversionType(Integer status){
        String response;
        switch (status){
            case 1:
                response = "待确认";
                break;
            case 2:
                response = "已确认";
                break;
            case 3:
                response = "已发货";
                break;
            case 4:
                response = "已收货";
                break;
            case 5:
                response = "已完成";
                break;
            case 6:
                response = "已取消";
                break;
            case 8:
                response = "捡货中";
                break;
            default:
                throw new IllegalStateException("Unexpected value: " + status);
        }
        return response;
    }

}
